const path = require('path')
const fs = require('fs')
const http = require('http')
const BufferHelper = require('bufferhelper')
let login_html = path.join(__dirname, '../public/auth/index.html')
let cofig_path = path.join(__dirname, '../modules.config.json')
let deploy_path = path.join(__dirname, '../modules.deploy.json')
const confg_modules = JSON.parse(fs.readFileSync(cofig_path))
module.exports =  async (ctx, next) => {
  if (!fs.existsSync(cofig_path) || !fs.existsSync(deploy_path)) {
    return next()
  }
  let requrl = ctx.request.url
  if (requrl.indexOf('/api/auth/legalize') > -1 || requrl.indexOf('login') > -1 || requrl === 'auth' || requrl === '/home' || requrl === '/api/user/testUser' || requrl.indexOf('init') > -1) {
    await next()
  } else {
    let token = ctx.cookies.get('token')
    if (token) {
      console.log('global.userCache ----------', global.userCache)
      // 如果token存在,则查找对应的session
      user = global.userCache[token]
      if (!user) {
        console.log('-------没有找到global.userCache[token]---------', ctx.request.url)
      }
      if (user) {
        await next()
      } else {
        // 调用授权接口,授权成功返回用户信息
        let port = ''
        confg_modules.map(item => {
          if (item.key === 'auth') {
            port = item.port
          }
        })
        ctx.request.url = '/api/auth/author'
        ctx.request.body.token = token
        ctx.request.method = 'post'
        ctx.request.header['content-type'] = 'application/json'
        httpRequest(ctx, {
          port: port
        }).then(res => {
          // console.log('res', res)
          global.userCache[token] = JSON.parse(res.body)
          // ctx.response.redirect('/auth/index.html')
          console.log('已执行 ---------ctx.response.redirect(/home)---------------')
          next()
        }).catch(err => {
          console.log(err)
        })
      }
    } else {
      ctx.response.redirect('/auth/index.html?target=/home')
      // await next()
    }
  }
}

const httpRequest = (ctx, opts) => {
  return new Promise((resolve) => {
      delete ctx.request.header.port;
      const options = {
          port: opts.port,
          path: ctx.request.url,
          method: ctx.request.method,
          headers: ctx.request.header
      }
      let requestBody={},
          body,
          head,
          chunks = [],
          fileFields,
          files,
          boundaryKey,
          boundary,
          endData,
          filesLength,
          totallength = 0;
      if (ctx.request.body && JSON.stringify(ctx.request.body) !== "{}") {
          if (ctx.request.header['content-type'].indexOf('application/x-www-form-urlencoded') > -1) {
            requestBody = ctx.request.body.toString()
              requestBody = JSON.stringify(requestBody)
              options.headers['Content-Length'] = Buffer.byteLength(requestBody)
          } else if (ctx.request.header['content-type'].indexOf('application/json') > -1) {
              requestBody = JSON.stringify(ctx.request.body);
              options.headers['Content-Length'] = Buffer.byteLength(requestBody)
          } else if (ctx.request.header['content-type'].indexOf('multipart/form-data') > -1) {
              fileFields = ctx.request.body.fields;
              files = ctx.request.body.files;
              boundaryKey = Math.random().toString(16);
              boundary = `\r\n----${boundaryKey}\r\n`;
              endData = `\r\n----${boundaryKey}--`;
              filesLength = 0;

              Object.keys(fileFields).forEach((key) => {
                  requestBody +=  `${boundary}Content-Disposition:form-data;name="${key}"\r\n\r\n${fileFields[key]}`;
              })

              Object.keys(files).forEach((key) => {
                  requestBody += `${boundary}Content-Type: application/octet-stream\r\nContent-Disposition: form-data; name="${key}";filename="${files[key].name}"\r\nContent-Transfer-Encoding: binary\r\n\r\n`;
                  filesLength += Buffer.byteLength(requestBody,'utf-8') + files[key].size;
              })

              options.headers['Content-Type'] = `multipart/form-data; boundary=--${boundaryKey}`;
              options.headers[`Content-Length`] = filesLength + Buffer.byteLength(endData);
          }
      } else {
          requestBody = JSON.stringify(ctx.request.body)
          options.headers['Content-Length'] = Buffer.byteLength(requestBody)
      }
      let req
      let bufferhelper = new BufferHelper()
      try {
        req = http.request(options, (res) => {
          res.on('data', (chunk) => {
            // let decoder = new StringDecoder('utf8')
            bufferhelper.concat(chunk)
            // console.log(chunk)
            //   chunks.push(chunk);
            //   totallength += chunk.length;
          })
          res.on('error', (e) => {
            console.log(e)
          })
          res.on('end', () => {
            // console.log(bufferhelper.toBuffer().toString())
              // body = JSON.parse(Buffer.concat(chunks, totallength).toString())
              body = bufferhelper.toBuffer().toString()
              head = res.headers
              resolve({head, body});
          })
        })
        ctx.request.body && req.write(requestBody);
      } catch (err) {
        console.log(err)
      }
      

      if (fileFields) {
          let filesArr = Object.keys(files);
          let uploadConnt = 0;
          filesArr.forEach((key) => {
              let fileStream = fs.createReadStream(files[key].path);
              fileStream.on('end', () => {
                  fs.unlink(files[key].path);
                  uploadConnt++;
                  if (uploadConnt == filesArr.length) {
                      req.end(endData)
                  }
              })
              fileStream.pipe(req, {end: false})
          })
      } else {
          req.end();
      }

  })
}